package com.puzzlebazar.client.heyawake;

import com.puzzlebazar.client.puzzle.model.History;
import com.puzzlebazar.client.puzzle.model.MoveTimer;
import com.puzzlebazar.client.squaregrid.control.CellStateControl;
import com.puzzlebazar.client.squaregrid.control.CellStateCycleControl;
import com.puzzlebazar.client.squaregrid.control.CellStateDirectControl;
import com.puzzlebazar.client.util.Releasable;

public class PlayState extends HeyawakeState implements Releasable {

	private CellStateControl control = null;
	
	boolean directControl = true;

	/**
	 * Creates a controller state for playing
	 * 
	 * @param model The associated model
	 * @param view The view for the heyawake
	 * @param controller The associated controller
	 * @param history History track into which to add the moves 
	 * @param moveTimer The move timer
	 */
	public PlayState(HeyawakeModel model, HeyawakeView view,
			HeyawakeController controller, History history, MoveTimer moveTimer ) {
		super(model, view, controller, history, moveTimer);
	}

	@Override
	public void enter() {	
		controller.enablePlay( false );
		controller.enableResize( false );
		
		assert( control == null );
		loadStateControl();		
	}

	@Override
	public void exit() {
		controller.enablePlay( true );
		controller.enableResize( true );

		assert( control != null );
		view.getControlDecorator().removeCellCallback( control );
		if( control != null )
			control.release();
		control = null;
	}

	/**
	 * Selects control mode. Direct control means the left button toggles
	 * on black cell and the right button (or shift-click) toggles white cell.
	 * Cycling control means the left button cycles: empty->black->white, while
	 * the right button (or shift-click) cycles the other way.
	 * 
	 * @param b True for direct control, false otherwise
	 */
	public void useDirectControl( boolean b ) {
		if( directControl != b ) {
			directControl = b;
			loadStateControl();
		}
				
	}

	private void loadStateControl() {
		releaseControl();
			
		control = getControl();
		try {
			control.setOnlyOverwritableState(HeyawakeModel.States.KNOWN_EMPTY, HeyawakeModel.States.EMPTY);
			control.setOnlyOverwritableState(HeyawakeModel.States.FILLED, HeyawakeModel.States.EMPTY);
			control.setCheckeredDrawing(HeyawakeModel.States.FILLED, true);
		} catch (Exception exception) {
			exception.printStackTrace();
		}

		view.getControlDecorator().addCellCallback( control );	
	}

	private void releaseControl() {
		if( control != null )
			view.getControlDecorator().removeCellCallback( control );
	}

	private CellStateControl getControl() {
		if( directControl )
			return new CellStateDirectControl(model, history, moveTimer);
		else
			return new CellStateCycleControl(model, history, moveTimer);
	}

	@Override
	public void release() {
		releaseControl();
	}
}
